/*
 * area.c
 *
 *  Created on: May 12, 2010
 *      Author: abeldantas
 */

#include "area.h"

void newGame() {
	polvo[0] = 0;
	polvo[1] = 0;
	polvo[2] = 0;
	polvo[3] = 0;
	polvo[4] = 0;
	polvo[5] = 0;
	polvo[6] = 0;
	polvo[7] = 0;
	polvo[8] = 0;
	polvo[9] = 0;
	song_finalize();
	song_init("zelda1.txt");

	char* up[3] = { "up1.xpm", "up2.xpm", "up3.xpm" };
	char* down[3] = { "down1.xpm", "down2.xpm", "down3.xpm" };
	char* left[3] = { "left1.xpm", "left2.xpm", "left3.xpm" };
	char* right[3] = { "right1.xpm", "right2.xpm", "right3.xpm" };

	int* a = (int*)15;
	int* b = (int*)25;
	int i = 0;

	//atribuicao dos xpms aos containers
	char **tempDown = (char**) malloc(3*(*a *HRES+ *b) * sizeof(char*));
	for (i = 0; i != 3; i++) {
		tempDown[i] = read_xpm_file(down[i], a, b);
	}
	playerDown = tempDown;
	char **tempLeft = (char**) malloc(3*(*a * HRES+ *b) * sizeof(char*));
	for (i = 0; i != 3; i++) {
		tempLeft[i] = read_xpm_file(left[i], a, b);
	}
	playerLeft = tempLeft;

		char **tempUp = (char**) malloc(3*(*a * HRES+ *b) * sizeof(char*));
	for (i = 0; i != 3; i++) {
		tempUp[i] = read_xpm_file(up[i], a, b);
	}
	playerUp = tempUp;


	char **tempRight = (char**) malloc(3*(*a * HRES+ *b) * sizeof(char*));
	for (i = 0; i != 3; i++) {
		tempRight[i] = read_xpm_file(right[i], a, b);
	}
	playerRight = tempRight;



	currentEvent = 1;

	do{
		switch (currentEvent) {
		case 1:
			clear_screen(0,base);
			startArea(&area1, "map1.xpm", "map1back.xpm", up, down, left, right,HRES / 2, VRES / 2,HRES / 2, VRES/3);
			updateArea(&area1);
			/*
			destroy_sprite(area1.map);
			destroy_sprite(area1.character);
			free(area1.collisions);
			free(&area1);
			*/
			clear_screen(0,base);
			break;
		case 2:
			clear_screen(0,base);
			startArea(&area2, "map2.xpm", "map2back.xpm", up, down, left, right,HRES / 2, VRES / 2,HRES / 2, VRES/2.8);
			updateArea(&area2);
			clear_screen(0,base);
			break;
		case 3:
			clear_screen(0,base);
			int a = 3.2;
			if(HRES == 800) a=4;
			startArea(&area3, "map3.xpm", "map3back.xpm", up, down, left, right,HRES / 2, VRES / 2,HRES / a, VRES / 2.2);
			updateArea(&area3);
			clear_screen(0,base);
			break;
		case 4:
			clear_screen(0,base);
			startArea(&area2, "map2.xpm", "map2back.xpm", up, down, left, right,HRES / 2, VRES / 2,HRES / 2,400);
			updateArea(&area2);
			clear_screen(0,base);
			break;
	}
	}while(currentEvent !=0);

	/*
	free(pallet.playerDown);
	free(pallet.playerLeft);
	free(pallet.playerRight);
	free(pallet.playerUp);
	free(pallet.collisions);
	delete_sprite(pallet.character, base);
	delete_sprite(pallet.map, base);
	destroy_sprite(pallet.character);
	destroy_sprite(pallet.map);
	free(&pallet);
	*/
}


void startArea(Area* area, char* mapFile, char* colisionFile, char** up,
		char** down, char** left, char** right, int startX, int startY, int pstartX, int pstartY) {
	//----------MAP-------------------//
	area->map = create_unbuffered_sprite_from_file(mapFile);
	area->collisions = read_xpm_file(colisionFile, &area->map->width,
			&area->map->height);
	//inicialiso o bgmap para evitar o smooth move
	area->map->bgmap = read_xpm_file(colisionFile, &area->map->width,
			&area->map->height);

	//----------CHARACTER---------------//
	area->character = create_unbuffered_sprite_from_file(down[0]);


	//alocacao de espaco para o container dos sprites para cada posicao;
	area->map->x = startX - (area->map->width)/2;
	area->map->y = startY - (area->map->height)/2;

	area->character->x = pstartX;
	area->character->y = pstartY;

	draw_sprite(area->map, base);
	draw_sprite(area->character, base);

}

void updateArea(Area* area) {

	int step = 0;
	int direction;
	do {
		scancode = queueGet(&keys_queue);
		//direction 0->up 1->down 2->left 3->right
		switch (scancode) {
		case 72://up
			direction = 0;
			break;
		case 80://down
			direction = 1;
			break;
		case 75://left
			direction = 2;
			break;
		case 77://right
			direction = 3;
			break;
		}

		if (scancode == 72 || scancode == 80||scancode == 75 || scancode == 77) {
			moveArea(area, direction, step);

			if (step == 2)
			{
				step = 0;
			}else{
				step++;
				}
		}
	} while (scancode != 1 && scancode != 2);

	if(scancode ==1)
	{
		currentEvent = 0;
	}

}

//direction 0->up 1->down 2->left 3->right
//redraw e update collisions & position
void moveArea(Area* area, int direction, int step) {
	int deltaMove = 5;

	switch (direction) {
	case 0://up
		if (checkCollision(area, 0, deltaMove)) {
			move_sprite(area->map, area->map->x, area->map->y + deltaMove, base);
			area->character->map = playerUp[step];
		}
		break;
	case 1://down
		if (checkCollision(area, 0, -deltaMove)) {
			move_sprite(area->map, area->map->x, area->map->y - deltaMove, base);
			area->character->map = playerDown[step];
		}
		break;
	case 2://left
		if (checkCollision(area, deltaMove, 0)) {
			move_sprite(area->map, area->map->x + deltaMove, area->map->y, base);
			area->character->map = playerLeft[step];
		}
		break;
	case 3://right
		if (checkCollision(area, -deltaMove, 0)) {
			move_sprite(area->map, area->map->x - deltaMove, area->map->y, base);
			area->character->map = playerRight[step];
		}
		break;
	}
	draw_sprite(area->character, base);
}

//direction 0->up 1->down 2->left 3->right
//redraw e update collisions & position
void moveCharacter(Area* area, int direction, int step) {
	int deltaMove = 5;
	//draw_sprite(area->map, base);

	switch (direction) {
	case 0://up
		if (checkCollision(area, 0, deltaMove)) {
			delete_sprite(area->character,base);
			area->character->map = playerUp[step];
			move_sprite(area->character, area->character->x, area->character->y - deltaMove, base);
		}
		break;
	case 1://down
		if (checkCollision(area, 0, -deltaMove)) {
			delete_sprite(area->character,base);
			area->character->map = playerDown[step];
			move_sprite(area->character,area->character->x, area->character->y + deltaMove, base);
		}
		break;
	case 2://left
		if (checkCollision(area, deltaMove, 0)) {
			area->character->map = playerLeft[step];
			delete_sprite(area->character,base);
			move_sprite(area->character,area->character->x - deltaMove, area->character->y, base);
		}
		break;
	case 3://right
		if (checkCollision(area, -deltaMove, 0)) {
		  area->character->map = playerRight[step];
			delete_sprite(area->character,base);
			move_sprite(area->character,area->character->x + deltaMove, area->character->y, base);
		}
		break;
	}
}

Bool checkCollision(Area* area, int xdir, int ydir) {
	//2 points to define the character collision surface
	//top_left = (xi,yi)   bottom_right = (xf,yf)
	int xi = (area->character->x - area->map->x) - xdir
			+ area->character->height / 2;
	int yi = (area->character->y - area->map->y) - ydir
			+ area->character->height / 2;
	int xf = (area->character->x - area->map->x) - xdir
			+ area->character->width;
	int yf = (area->character->y - area->map->y) - ydir
			+ area->character->height;

	int top_left = (area->collisions)[area->map->width * yi + xi];
	int top_right = (area->collisions)[area->map->width * yi + xf];
	int bottom_left = (area->collisions)[area->map->width * yf + xi];
	int bottom_right = (area->collisions)[area->map->width * yf + xf];


	int temp = 31;
	if(bottom_left!=31)temp=bottom_left;
	if(bottom_right!=31)temp=bottom_right;
	if(top_left!=31)temp=top_left;
	if(top_right!=31)temp=top_right;
	//
	switch (temp) {
		//--------------------AREA1--------------------//
		//amarelo teleport da area 1 para area 2
		case 44:

				if(polvo[0] != 0 && polvo[1] !=0 && polvo[2] != 0)
				{
					drawDialog("Eu","Vou explorar mais um pouco.\nNao vale a pena ficar aqui.\nDepois nao posso voltar para tras.");
					currentEvent = 2;
					scancode = 2;
				}
				else
				{
					drawDialog("Eu","E melhor perguntar mais umas coisas\nantes de me ir embora.");
					clear_screen(0,base);
					draw_sprite(area->map, base);
					draw_sprite(area->character, base);
				}

				break;
		//verde claro, polvo1
		case 95:

				if(polvo[0] == 0)
				{
					drawDialog("Bob, o Polvo","Ola, eu sou o Bob, o Polvo!\nOnde estao os teus tentaculos?\n");
					polvo[0] = 1;
				}
				else
					drawDialog("Bob, o Polvo","Es estranho, nao tens tentaculos.\nVai-te embora.");
				clear_screen(0,base);
				draw_sprite(area->map, base);
				draw_sprite(area->character, base);
				break;
		//azul, polvo2
		case 32:

				if(polvo[2] == 0)
					drawDialog("John, o polvo","Um novato. Vai falar com o Lucas.");
				else
				{
					drawDialog("John, o polvo","Sim, o Lucas e um inutil. Se\nqueres voltar ao teu mundo, \nprocede e vai falar com o chefe polvo.");
					polvo[1] = 1;
				}
				clear_screen(0,base);
				draw_sprite(area->map, base);
				draw_sprite(area->character, base);
				break;
		//roxo, polvo 3
		case 20:
				if(polvo[2] == 0)
				{
					drawDialog("Lucas, o polvo","Glub glub blah.\nAdoro o mundo dos polvos.");
					polvo[2]=1;
				}
				else
					drawDialog("Lucas, o polvo","Glub glub blah.\nVai falar com o John\nGlub.");
				clear_screen(0,base);
				draw_sprite(area->map, base);
				draw_sprite(area->character, base);
				break;
//--------------------AREA2--------------------//
		//vermelho teleport da area 2 para area 1
		case 40:
				drawDialog("Eu","Nao vou para tras agora...\nO caminho para casa deve ser para\na frente, para tras so ha polvos...");
				clear_screen(0,base);
				draw_sprite(area->map, base);
				draw_sprite(area->character, base);
				/*
				currentEvent = 1;
				drawDialog("DEGUG","This is supposed to teleport you to area1 via area2");
				scancode = 97;;
				*/
				break;
//--------------------AREA3--------------------//
	//salmao teleport da area 2 para zona 3
		case 65:
				currentEvent = 3;
				drawDialog("Eu","Vamos entao falar com o chefe polvo,\nmas antes e melhor falar com\nos polvos a volta.");
				scancode = 2;
				break;

	//cinzento escuro teleport da area 3 para a area 2
		case 21:
				drawDialog("Eu","Nao vou para tras agora...\nO caminho para casa deve ser para\na frente, para tras so ha polvos...");
				clear_screen(0,base);
				draw_sprite(area->map, base);
				draw_sprite(area->character, base);
				/*
				currentEvent = 4;
				drawDialog("DEGUG","This is supposed to teleport you to area3 via area2");
				scancode = 97;;
				*/
				break;
		//vermelho escuro, polvo4 vermelho
		case 112:
				drawDialog("Samuel, o polvo","Com que entao vens falar com\no chefe. Dica: Nao fales com ele antes\nde falar com o Blob.");
				polvo[3]=1;
				clear_screen(0,base);
				draw_sprite(area->map, base);
				draw_sprite(area->character, base);
			break;
		//verde, polvo5 verde
		case 121:
				if(polvo[4] == 0)
				{
					drawDialog("Blob, o polvo","Queres voltar ao teu mundo?\nJa contava, por isso disse ao Gabu\npara te guiar. Fala-lhe.");
					polvo[4]=1;
				}
				else
				{
					drawDialog("Blob, o polvo","O Gabu esta a tua espera.");
				}
				clear_screen(0,base);
				draw_sprite(area->map, base);
				draw_sprite(area->character, base);
			break;
		//laranja, polvo6 laranja
		case 6:
				if(polvo[4]==0)
				{
					drawDialog("Gabu, o polvo","Agora estou a meditar.\nVolta daqui a pouco.");
				}
				else if(polvo[4]==1 && polvo[5]==0)
				{
					drawDialog("Gabu, o polvo","CHIMACHANGA!\nAgora o chefe ja nao desconfia\nde ti...");
					polvo[5]=1;
				}
				else if(polvo[4]==1 && polvo[5]==1)
				{
					drawDialog("Gabi, o polvo","Nao deixes o polvo chefe\na espera por favor...");
				}
				clear_screen(0,base);
				draw_sprite(area->map, base);
				draw_sprite(area->character, base);
			break;
		//azul escuro, polvo7 azul
		case 80:
				drawDialog("Lucifer, o polvo","Glub Glub...");
				clear_screen(0,base);
				draw_sprite(area->map, base);
				draw_sprite(area->character, base);
			break;

		//azul claro, polvo8 robot
		case 79:
				song_finalize();
				song_init("overworld.txt");
				if(polvo[5]==0)
				{
					drawDialog("OctoChefe","Ninguem passara por aqui!");
					clear_screen(0,base);
					draw_sprite(area->map, base);
					draw_sprite(area->character, base);
					drawDialog("Narrador","O chefe polvo atacou-te\nviolentamente e morreste.\n");
					clear_screen(0,base);
					draw_sprite(area->map, base);
					draw_sprite(area->character, base);
					drawDialog("Narrador","E ficaste com liquido de\npolvo na cara.");
					clear_screen(0,base);
					draw_sprite(area->map, base);
					draw_sprite(area->character, base);
					currentEvent = 0;
					scancode = 1;
				}
				else
				{

					drawDialog("OctoChefe","O Gabi comunicou-me a tua\nsituacao. Responde apenas\na uma pergunta:");
					clear_screen(0,base);
					draw_sprite(area->map, base);
					draw_sprite(area->character, base);
					drawDialog("OctoChefe","Qual a raiz quadrada de 25?");
					clear_screen(0,base);
					draw_sprite(area->map, base);
					draw_sprite(area->character, base);
					drawDialog("Eu","^) 5\n>)0\nV)O que e isso?");
					int resposta=0;
					do {
						
						scancode = queueGet(&keys_queue);
						//direction 0->up 1->down 2->left 3->right
						switch (scancode) {
						case 72://up
							resposta = 1;
							break;
						case 80://down
							resposta = 3;
							break;
						case 77://right
							resposta = 2;
						break;
						}

						if (resposta == 1)
						{
							//WIN
							clear_screen(0,base);
							draw_sprite(area->map, base);
							draw_sprite(area->character, base);
							drawDialog("OctoChefe","Resposta certa. Lancarte-ei\num feitico para voltares\nao teu mundo.");
							clear_screen(0,base);
							draw_sprite(area->map, base);
							draw_sprite(area->character, base);
							drawDialog("Narrador","E assim foi a historia\ndo nosso heroi no mundo\ndos polvos.");
							currentEvent = 0;
							scancode = 1;
							
						}
						else if (resposta == 2 || resposta == 3)
						{
							//lose
							clear_screen(0,base);
							draw_sprite(area->map, base);
							draw_sprite(area->character, base);
							drawDialog("Narrador","O chefe polvo atacou-te\nviolentamente e morreste.\n");
							clear_screen(0,base);
							draw_sprite(area->map, base);
							draw_sprite(area->character, base);
							drawDialog("Narrador","E ficaste com liquido de\npolvo na cara.");
            							currentEvent = 0;
							scancode = 1;
						}
					} while (resposta == 0);

				}
				clear_screen(0,base);
				draw_sprite(area->map, base);
				draw_sprite(area->character, base);
				song_finalize();
				song_init("mm1bomb.txt");
			break;
				}
	return (top_left == 31 && top_right == 31 && bottom_left == 31 && bottom_right == 31);

}
